package com.depth.viewer.widget
{
	import com.depth.viewer.container.IWidgetContainer;
	import com.depth.viewer.container.ViewerContainer;
	import com.depth.viewer.events.AppEvent;
	import com.depth.viewer.facade.IocAppFacade;
	import com.depth.viewer.widget.definition.IBaseWidgetDefinition;
	import com.depth.viewer.widget.definition.IWidgetDefinition;
	import com.depth.viewer.widget.template.IWidgetTemplate;
	
	import flash.display.Sprite;
	
	import mx.events.FlexEvent;
	import mx.modules.Module;
	
	import org.puremvc.as3.interfaces.INotification;
	
	
	[Event(name="widgetConfigLoaded", type="flash.events.Event")]
	[Event(name="onChainRequest", type="com.esri.viewer.AppEvent")]
	
	
	public class BaseWidget extends Module implements IBaseWidget,IBaseMediatorWidget
	{
		
		
		
		public static const DROP_FOMAT:String = "widgetDragDrop";
		
		
		private static const VIEWER_STRINGS:String = "ViewerStrings";
		
		
		private static const WIDGET_CONFIG_LOADED:String = "widgetConfigLoaded";
		
		
		[Binbale]
		private var _definition:IWidgetDefinition;
		public var _container:IWidgetContainer;
		[Binbale]
		private var _map:Object;
		
		public function BaseWidget()
		{
			super();
			this.autoLayout = true;
			
			addEventListener(FlexEvent.CREATION_COMPLETE, createCompleteHandler);
			//addEventListener(MouseEvent.MOUSE_OVER,mouse_overHandler);
		}
		private function createCompleteHandler(event:FlexEvent):void{
			initWidgetTemplate();
		}
		public function set container(value:IWidgetContainer):void{
			this._container = value;
		}
		public function get container():IWidgetContainer{
			return this._container;
		}
		
		[Bindable]
		public function get map():Object{
			if(_map){
				return _map;
			}else{
				return IocAppFacade.getInstance().map;
			}
		}
		
		protected var _mapCreationCompleted:Boolean = false;
		
		
		public function set map(map:Object):void{
			this._map = map;
			
			if(map && !_mapCreationCompleted){
				mapCreationCompleteHandler();
				_mapCreationCompleted = true;
			}else{
				invalidateProperties();
			}
		}
		
		
		protected function mapCreationCompleteHandler():void{
			
		}
		
		[Bindable]
		private var _widgetIcon:String = "";
		[Bindable]
		private var _widgetTitle:String = "";
		
		[Bindable]
		private var _widgetId:String;
		private var _widgetConfig:String;
		private var _widgetPreload:String;
		
		protected var _widgetState:String;
		private var _widgetStateFag:Boolean = false;
		
		protected var _widgetTemplates:Vector.<IWidgetTemplate> = new Vector.<IWidgetTemplate>();
		public function get widgetTemplates():Vector.<IWidgetTemplate>{
			return _widgetTemplates;
		}
		
		private var _isDraggable:Boolean = true;
		private var _isDragDropable:Boolean = false;
		private var _isResizeable:Boolean = true;
		
		private var _isDraggableFag:Boolean = false;
		private var _isResizeableFag:Boolean = false;
		private var _isDragDropableFag:Boolean = false;
		
		
		
		public function set isDraggable(value:Boolean):void
		{
			_isDraggableFag = true;
			
			_isDraggable = value;
			
			invalidateProperties();
		}
		public function get isDraggable():Boolean
		{
			return _isDraggable;
		}
		
		
		public function set isDragDropable(value:Boolean):void{
			_isDragDropableFag = true;
			
			this._isDragDropable = value;
			
			invalidateProperties();
		}
		public function get isDragDropable():Boolean{
			return this._isDragDropable;
		}
		
		
		public function get isResizeable():Boolean
		{
			return _isResizeable;
		}
		public function set isResizeable(value:Boolean):void
		{
			_isResizeableFag = true;
			
			_isResizeable = value;
			
			invalidateProperties();
		}
		
		public function setState(value:String):void
		{
			_widgetStateFag = true;
			
			_widgetState = value;
			
			invalidateProperties();
		}
		public function getState():String{
			return this._widgetState;
		}
		private function notifyStateChanged(widgetState:String):void
		{
			var data:Object =
				{
					id: this._widgetId,
						state: widgetState
				};
			ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_STATE_CHANGED, data));
		}
		//----------------------------------
		//  widget id
		//----------------------------------
		
		
		public function get widgetId():String
		{
			return _widgetId;
		}
		
		
		public function set widgetId(value:String):void
		{
			_widgetId = value;
		}
		
		//----------------------------------
		//  widget title
		//----------------------------------    
		
		public function get widgetTitle():String
		{
			return _widgetTitle;
		}
		
		[Bindable]
		public function set widgetTitle(value:String):void
		{
			_widgetTitle = value;
		}
		
		//----------------------------------
		//  widget icon
		//----------------------------------
		
		public function get widgetIcon():String
		{
			return _widgetIcon;
		}
		
		
		public function set widgetIcon(value:String):void
		{
			_widgetIcon = value;
		}
		
		override protected function commitProperties():void{
			super.commitProperties();
			if(_isDragDropableFag || _isResizeableFag || _isDraggableFag){
				_isDragDropableFag = false;
				_isDraggableFag = false;
				_isResizeableFag = false;
				setWidgetTemplateControl();
			}
			if(_widgetStateFag){
				_widgetStateFag = false;
				if(_widgetTemplates.length == 0){
					switch(_widgetState){
						case WidgetStates.WIDGET_OPENED:
							ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_OPEN_START,this));
							ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_OPEN_END,this));
							
							ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_OPEND,this));
							break;
						case WidgetStates.WIDGET_MINIMIZED:
							ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_MINIMIZE_START,this));
							ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_MINIMIZE_END,this));
							
							ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_MINIMIZED,this));
							break;
						case WidgetStates.WIDGET_CLOSED:
							ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_CLOSE_START,this));
							ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_CLOSE_END,this));
							
							ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_CLOSED,this));
							break;
					}
				}
				for each(var _widgetTemplate:IWidgetTemplate in _widgetTemplates){
					if (_widgetTemplate)
					{
						_widgetTemplate.widgetState = _widgetState;
						if(_widgetState == WidgetStates.WIDGET_CLOSED){
							_widgetTemplate.close();
						}
					}
				}
				notifyStateChanged(_widgetState);
			}
			
			
			map = IocAppFacade.getInstance().map;
		}
		
		protected function initWidgetTemplate(childContainer:Sprite = null):void
		{
			
			if(definition && definition is IBaseWidgetDefinition)
				_widgetTitle = IBaseWidgetDefinition(definition).label;
			
			if(!childContainer){
				childContainer = this;
			}
			var numChildren:int = childContainer.numChildren
			for(var i:int = 0;i < numChildren; i++)
			{
				var child:Object = childContainer.getChildAt(i);
				if (child is IWidgetTemplate)
				{
					var _widgetTemplate:IWidgetTemplate = child as IWidgetTemplate;
					_widgetTemplates.push(_widgetTemplate);
					
					_widgetTemplate.baseWidget = this;
					if(_widgetTitle && _widgetTitle.length > 0)
						_widgetTemplate.title = _widgetTitle;
					_widgetTemplate.widgetIcon = _widgetIcon;
					if (_widgetState)
					{
						_widgetTemplate.widgetState = _widgetState;
					}
					
					if (_widgetPreload == WidgetStates.WIDGET_MINIMIZED)
					{
						_widgetTemplate.widgetState = WidgetStates.WIDGET_MINIMIZED;
					}
					
					
				}else if(child is Sprite && Sprite(child).numChildren > 0){
					initWidgetTemplate(child as Sprite);
				}
			}
			setWidgetTemplateControl();
		}
		
		private function setWidgetTemplateControl():void
		{
			/*var children:Array = this.getChildren();
			for each (var child:Object in children)
			{
			if (child is IWidgetTemplate)
			{
			var _widgetTemplate:IWidgetTemplate = child as IWidgetTemplate;
			_widgetTemplate.resizable = isResizeable;
			_widgetTemplate.draggable = isDraggable;
			_widgetTemplate.dragDropable = isDragDropable;
			}
			}*/
		}
		
		
		
		/**
		 * This will display an error message window.
		 */
		public function showError(errorMessage:String):void
		{
			ViewerContainer.dispatchEvent(new AppEvent(AppEvent.APP_ERROR, errorMessage));
		}
		
		public function updateDisplayPosition():void{
			//setRelativePosition(Number(left),Number(right),Number(top),Number(bottom));
		}
		public function setXYPosition(x:Number, y:Number,z:Number = -1):void
		{
			this.setLayoutBoundsPosition(x, y);
			if(z != -1){
				this.z = z;
			}
		}
		
		public function setRelativePosition(left:Object = null, right:Object = null, top:Object = null, bottom:Object = null):void
		{
			if (left != null && left != this.left)
			{
				//this.x = left as Number;
				this.left = left;
			}
			
			if (top != null && top != this.top)
			{
				//this.y = top;
				this.top = top;
			}
			if (right != null && right != this.right)
			{
				//this.x = DisplayObject(container).width - right - this.width;
				this.right = right;
			}
			if (bottom != null && bottom != this.bottom)
			{
				//this.y = DisplayObject(container).height - bottom - this.height;
				this.bottom = bottom;
			}
			
			/*if (left != null && left != this.left)
			{
			//this.x = left as Number;
			this.x = left as Number;
			this.left = undefined;
			}
			
			if (top != null && top != this.top)
			{
			//this.y = top;
			this.y = top as Number;
			this.top = undefined;
			}
			if (right != null && width && container)
			{
			this.x = DisplayObject(container).width - (Number(right) + width);
			this.right = undefined;
			//this.x = parent.width - (right + width);
			}else if(right != null && right != this.right){
			this.right = right;
			invalidateDisplayList();
			}
			if (bottom != null && height && container)
			{
			this.y = DisplayObject(container).height - (Number(bottom) - height);
			this.bottom = undefined;
			//this.y = parent.height - (bottom + top);
			}else if(bottom != null && bottom != this.bottom){
			this.bottom = bottom;
			invalidateDisplayList();
			}*/
		}
		/**
		 *子类重写此方法，在加载模块后会调用此方法 
		 * 不应该直接调用此方法，框架在卸载模块时会自动调用
		 * @param runingParams  加载模块时初始化的参数
		 * 
		 */		
		public function run(runingParams:Object = null):void
		{
			ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_RUN,this));
			map = map;
		}
		/**
		 *子类重写此方法，在删除模块时会调用此方法 
		 * 不应该直接调用此方法，框架在卸载模块时会自动调用
		 */		
		public function stop():void{
			ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_STOP,this));
		}
		/**
		 * 子类重写此方法，在卸载模块时会调用此方法以进行内在清理工作，
		 * 不应该直接调用此方法，框架在卸载模块时会自动调用
		 * 
		 */		
		public function destroy():void{
			
		}
		
		public function get definition():IWidgetDefinition{
			return this._definition;
		}
		public function set definition(value:IWidgetDefinition):void{
			this._definition = value;
		}
		
		
		public function getDefaultString(resourceName:String):String
		{
			return resourceManager.getString(VIEWER_STRINGS, resourceName);
		}
		
		private var progressBar:LoadingGroup = new LoadingGroup();
		protected function visibleLoading(visible:Boolean,width:Number = 50,height:Number = 50,x:Number = 0,y:Number = 0):void{
			progressBar.width = width;
			progressBar.height = height;
			progressBar.x = x;
			progressBar.y = y;
			if(visible){
				addElementAt(progressBar,numElements);
			}else{
				if(contains(progressBar))
					removeElement(progressBar);
			}
		}
		
		public function listNotificationInterests():Array{
			return [];
		}
		public function handleNotification(notification:INotification):void{
			
		}
	}
}
